/*
 *  Couleur.h
 *  Ray Tracing
 *
 *  La classe couleur. Definit la couleur et les differentes methodes
 *  utiliser pour la modifer, la comparer...
 *
 *  Created by Jean-Marc Comby + Romain Dequesne on Sat Mar 20 2004.
 *  Copyright (c) 2004. All rights reserved.
 *
 * Calcul de l'intensité par Johan "Solo" Luisier 2009.
 *
 */
#ifndef _COULEUR_H
#define _COULEUR_H

#include <iostream>

#include "ComposantCouleur.hpp"

#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/functional.hpp>

/*
 * Alias utilisé pour le type des composantes. En principe on peut
 * remplacer "unsigned char" par "unsigned short" pour passer de 24
 * bits à 48 bits.
 */
//typedef unsigned char ComposantCouleur;

/**
 * Classe qui définit ce qu'est une couleur en terme de
 * composantes. Une Couleur est un triplet de nombre, qui
 * correspondent aux valeurs rgb (rvb). Les différentes méthodes pour
 * modifier, comparer, combiner ces Couleurs sont implémentées.
 *
 * Le code est en principe compatible avec différents types pour
 * représenter les composantes. Pour le moment les instances sont
 * codées en 24 bits (1 byte par composante).
 *
 * @author Jean-Marc Comby + Romain Dequesne
 * @author Johan "Solo" Luisier
 *
 *  @date 20 Mars 2004
 */
class Couleur : public boost::numeric::ublas::vector< ComposantCouleur >
{
 private:
  /*
   * Tableau des composantes. L'ordre est donné par RGB.
   */
  //ComposantCouleur rvb[3]; // Les trois composantes de la couleurs

  //static ComposantCouleur MaxComposante;
 public:
  //static const ComposantCouleur& maxComposante();

  // Les constructeurs
  // Constructeur avec des valeurs RVB
  Couleur(const ComposantCouleur& rouge = 0,
	  const ComposantCouleur& vert = 0,
	  const ComposantCouleur& bleu = 0);
  Couleur(const int& rouge,
	  const int& vert,
	  const int& bleu);
  // Constr copie
  Couleur(Couleur const &);
  // destructeur
  virtual ~Couleur();
	
  // Methode pour assigner la couleur
  void setRouge(const ComposantCouleur& rouge);
  void setVert(const ComposantCouleur& vert);
  void setBleu(const ComposantCouleur& bleu);
  void setCouleur(const ComposantCouleur& rouge,
		  const ComposantCouleur& vert,
		  const ComposantCouleur& bleu);
	
  // Methode pour lire la couleur
  const ComposantCouleur& rouge() const;
  const ComposantCouleur& vert() const;
  const ComposantCouleur& bleu() const;
  double intensite() const;
	
  // Les methodes de calcul sur RVB et l'affichage RVB
  // L'addition
  Couleur &operator+=(const Couleur &);
  Couleur operator+(const Couleur &) const;
  // Soustraction
  Couleur &operator-=(const Couleur &);
  Couleur operator-(const Couleur &) const;
  // Multiplication par un double
  Couleur &operator*=(const double&);
  Couleur operator*(const double&) const;
  // Comparaison de 2 couleurs
  bool operator==(const Couleur &);
  // Affichage
  friend std::ostream& operator<<(std::ostream &, const Couleur &);
  // Affiche RVB
  void affiche();
	
  // Les methodes qui modifie les couleurs
  Couleur& attenue(const double& coef);
  Couleur& melange(const Couleur& autre, const double& proportion);
  Couleur& eclairee(const Couleur& lumiere);
};
#endif
